import {IProcedureManager} from "./IProcedureManager";
import {ProcedureBase} from "./ProcedureBase";
import {IFsmManager} from "../Fsm/IFsmManager";
import {IFsm} from "../Fsm/IFsm";
import ccclass = cc._decorator.ccclass;
import GameFrameworkModule from "../Base/GameFrameworkModule";
@ccclass("ProcedureManager")
export default class ProcedureManager implements GameFrameworkModule,IProcedureManager{
    private _FsmManager:IFsmManager&GameFrameworkModule;
    private _ProcedureFsm:IFsm<IProcedureManager>;

    constructor() {
        this._FsmManager = null;
        this._ProcedureFsm = null;
    }

    CurrentProcedure(): ProcedureBase {
        if(this._ProcedureFsm == null){
            throw new Error("_ProcedureFsm is null");
        }
        return this._ProcedureFsm.CurrentState();
    }

    CurrentProcedureTime(): number {
        if(this._ProcedureFsm == null){
            throw new Error("_ProcedureFsm is null");
        }
        return this._ProcedureFsm.CurrentStateTime();
    }

    GetProcedure<T extends ProcedureBase>(type: { prototype: T }): ProcedureBase {
        return this._ProcedureFsm.GetState(type);
    }

    HasProcedure<T extends ProcedureBase>(type: { prototype: T }): boolean {
        return this._ProcedureFsm.HasState(type);
    }

    Initialize(fsmManager: IFsmManager&GameFrameworkModule, procedures: ProcedureBase[]): void {
        if(fsmManager == null){
            throw new Error("fsmManager is valid");
        }
        this._FsmManager = fsmManager;
        this._ProcedureFsm = <IFsm<IProcedureManager>>this._FsmManager.CreateFsm(this,"ProcedureManager",procedures);
    }

    get Priority(): number {
        return 970;
    }

    Shutdown(): void {
        if(this._FsmManager!= null){
            if(this._ProcedureFsm != null){
                this._FsmManager.DestroyFsm("ProcedureManager",this);
                this._ProcedureFsm = null;
            }
            this._FsmManager = null;
        }
    }

    StartProcedure<T extends ProcedureBase>(type:{ prototype: T }): void {
        this._ProcedureFsm.Start(type);
    }

    Update(elapseSeconds: number, realElapseSeconds: number): void {
    }

    get baseName(): string {
        return "GameFrameworkModule";
    }

}